package poolserver

//func (ctx *ConnContext) transLeftDataToBackend() error {
//    var err error
//    var isSrc bool
//	zap.S().Infof("Client(%d): SB: data=%v", ctx.Pid, ctx.rewritebuf[:])
//	err, isSrc = transData(ctx.cliConn, ctx.pBackConn.Conn, ctx.leftLen, ctx.recvBuf[:])
//	if err != nil {
//		if isSrc { /* 是客户端连接中断*/
//			zap.S().Infof("Client(%d): SB(%d): forward failed: client error", ctx.Pid, ctx.pBackConn.Id)
//			/* 做一些清理工作，把此后端连接上的事务回滚掉*/
//			/* FIXME: 有可能需要把后端连接也停掉*/
//			if ctx.transState != 'I' {
//				CleanupTrans(ctx.pBackConn.Conn)
//			}
//			atomic.StoreInt32(&ctx.pBackConn.State, 0)
//			return err
//		} else { /* 后端连接中断 */
//			zap.S().Infof("Client(%d, Q): SB(%d): forward failed: backend error", ctx.Pid, ctx.pBackConn.Id)
//			ctx.cliConn.Close()
//			ctx.pBackConn.Reconnect()
//			atomic.StoreInt32(&ctx.pBackConn.State, 0)
//			return err
//		}
//	}
//	return nil
//}

/*
返回clientErr, backendErr
*/
// func (ctx *ConnContext) forwardToClientOld() (error, error) {
// 	var isSuccess bool
// 	var n int
// 	var clientErr error = nil
// 	var backendErr error = nil
// 	var pos int
// 	var pktpos int
// 	var pktlen int
// 	var msgType byte

// 	//var partialHappened bool = false

// 	//TCHDEBUG zap.S().Infof("*****RETURN Backend(%d) => Client(%d)", ctx.pBackConn.Id, ctx.Pid)

// 	if ctx.pSendBackConn.Id != ctx.pBackConn.Id {
// 		zap.S().Panicf("recv backend not the send backend!!!")
// 	}

// 	isSuccess = true
// 	pos = 0    //记录缓冲区记录数据的点
// 	pktpos = 0 //记录消息的开始位置
// 	for {
// 		//partialHappened = false
// 		//TCHDEBUG zap.S().Infof("Client(%d): RB(%d): begin ...", ctx.Pid, ctx.pBackConn.Id)
// 		n, backendErr = ctx.pBackConn.Conn.Read(ctx.recvBuf[pos : DEFAULT_BUF_SIZE-MAX_ERROR_MSG_SIZE])
// 		if backendErr != nil {
// 			zap.S().Infof("Client(%d): RB(%d): ERROR: %s", ctx.Pid, ctx.pBackConn.Id, backendErr.Error())
// 			ctx.cliConn.Close()
// 			ctx.BeReconnect()
// 			return clientErr, backendErr
// 		}
// 		pos += n
// 		for pktpos < pos {
// 			msgType = ctx.recvBuf[pktpos]
// 			/*保证包中的4字节长度字节都被接收下来了(如果没有收下来，会再次收下来*/
// 			if pktpos > pos-5 {
// 				//partialHappened = true
// 				//TCHDEBUG zap.S().Infof("Client(%d): RB(%d): begin ...", ctx.Pid, ctx.pBackConn.Id)
// 				n, backendErr = ctx.pBackConn.Conn.Read(ctx.recvBuf[pos:DEFAULT_BUF_SIZE])
// 				if backendErr != nil {
// 					zap.S().Infof("Client(%d): RB(%d): ERROR: %s", ctx.Pid, ctx.pBackConn.Id, backendErr.Error())
// 					ctx.cliConn.Close()
// 					ctx.Beect()
// 					return clientErr, backendErr
// 				}
// 				pos += n
// 				continue
// 			}

// 			pktlen = int(binary.BigEndian.Uint32(ctx.recvBuf[pktpos+1 : pktpos+5]))
// 			if pktlen > int(DEFAULT_BUF_SIZE) || pktlen < 4 {
// 				zap.S().Infof("message is too long(more then %d)", DEFAULT_BUF_SIZE)
// 			}
// 			//zap.S().Infof("Client(%d): RB(%d): %c%d", ctx.Pid, ctx.pBackConn.Id, msgType, pktlen)

// 			/* 保证Z、E包都接收下来了*/
// 			if (msgType == 'Z' || msgType == 'E') && pktpos+pktlen+1 > pos {
// 				if pktlen > int(MAX_ERROR_MSG_SIZE)-1 {
// 					zap.S().Panicf("E message too long(%d more then %d)!!!", pktlen, MAX_ERROR_MSG_SIZE-1)
// 				}

// 				//TCHDEBUG zap.S().Infof("Client(%d): RB(%d): begin ...", ctx.Pid, ctx.pBackConn.Id)
// 				n, backendErr = ctx.pBackConn.Conn.Read(ctx.recvBuf[pos:DEFAULT_BUF_SIZE])
// 				if backendErr != nil {
// 					zap.S().Infof("Client(%d): RB(%d): ERROR: %s", ctx.Pid, ctx.pBackConn.Id, backendErr.Error())
// 					ctx.cliConn.Close()
// 					ctx.BeReconnect()
// 					return clientErr, backendErr
// 				}
// 				pos += n
// 				continue

// 			}

// 			if msgType == 'Z' {
// 				ctx.transState = ctx.recvBuf[pktpos+5]
// 			}
// 			if msgType == 'E' {
// 				isSuccess = false
// 				printBackendErrorMessage(ctx.recvBuf[pktpos:])
// 			}

// 			pktpos += pktlen + 1
// 		}

// 		//if pktpos > pos {
// 		//	zap.S().Infof("pktpos(%d) > pos(%d)", pktpos, pos)
// 		//}

// 		//if partialHappened {
// 		//	zap.S().Infof("partial happened!!!")
// 		//}

// 		if clientErr == nil {
// 			//TCHDEBUG zap.S().Infof("Client(%d): SC: data=%c%d%v", ctx.Pid, ctx.recvBuf[0], n, ctx.recvBuf[:n])
// 			_, clientErr = sendData(ctx.cliConn, ctx.recvBuf[0:pos])
// 			if clientErr != nil {
// 				zap.S().Infof("Client(%d): SC: ERROR: %s", ctx.Pid, clientErr.Error())
// 				ctx.cliConn.Close()
// 			}
// 		}

// 		if msgType == 'Z' && pktpos == pos {
// 			break
// 		}

// 		pktpos -= pos
// 		pos = 0
// 	}

// 	if clientErr != nil {
// 		isSuccess = false
// 	}
// 	if isSuccess {
// 		if !ctx.isInUnnamedPrepared {
// 			for prepareName, cuPre := range ctx.cupreMap {
// 				var pdata *PrepareData
// 				if cuPre.prepareRequestLen == 0 { /* 这是prepare的数据已缓存，而之前这个backend没有parse的情况*/
// 					var ok bool
// 					pdata, ok = ctx.cachedPrepare.Get(prepareName)
// 					if !ok {
// 						zap.S().Panicf("BUG!!!!!!")
// 					}
// 				} else {
// 					pdata = new(PrepareData)
// 					ctx.cachedPrepare.AddPrepare(prepareName, pdata)
// 					pdata.PrepareRequest = cuPre.prepareRequestData
// 				}

// 				pdata.BackendMap = make(map[int32]*PrepareInBackend)
// 				pib := new(PrepareInBackend)
// 				pib.PrepareId = cuPre.backendPrepareId
// 				pib.BackConn = ctx.pBackConn
// 				pib.ReConnCnt = ctx.pBackConn.ReConnCnt /* 把后端连接的当前重连次数记录下来，如果在以后，后端重连后，两者就不一样了，就知道后端被重连了*/
// 				pdata.BackendMap[ctx.pBackConn.Id] = pib
// 				zap.S().Infof("Client(%d): store prepare name=%s to backend(%d), backendPrepareId=%d",
// 					ctx.Pid, prepareName, ctx.pBackConn.Id, cuPre.backendPrepareId)
// 			}
// 			if len(ctx.cupreMap) > 1 {
// 				zap.S().Infof("many prepare in one request!")
// 			}
// 		}
// 	}

// 	/*把临时放prepare data的map清空*/
// 	ctx.cupreMap = make(map[string]*CuPre)

// 	if (clientErr != nil) || (backendErr != nil) { /*出现一些问题*/
// 		/* 做一些清理工作，把此后端连接上的事务回滚掉*/
// 		if ctx.transState != 'I' {
// 			zap.S().Infof("Client(%d, S): Client is closed, cleanup backend(%d) transacation",
// 				ctx.Pid, ctx.pBackConn.Id)
// 			CleanupTrans(ctx.pBackConn.Conn)
// 		}
// 		if ctx.isGetBackend {
// 			zap.S().Infof("Client(%d, S): release backend(%d)", ctx.Pid, ctx.pBackConn.Id)
// 			atomic.StoreInt32(&ctx.pBackConn.State, 0)
// 			ctx.isGetBackend = false
// 		}
// 		return clientErr, backendErr
// 	}

// 	if !isSuccess {
// 		//zap.S().Panicf("Client(%d, S): ERROR debug!!!", ctx.Pid)
// 	}

// 	/*这是没有发生错误的情况*/
// 	if ctx.transState == 'I' { /*释放后端连接*/
// 		//TCHDEBUG zap.S().Infof("Client(%d, S): release backend(%d)", ctx.Pid, ctx.pBackConn.Id)
// 		atomic.StoreInt32(&ctx.pBackConn.State, 0)
// 		ctx.isGetBackend = false
// 		ctx.pBackConn = nil
// 	}
// 	return nil, nil
// }

// /*
// 返回clientErr, backendErr
// */
// func (ctx *ConnContext) forwardToClient2() (error, error) {
// 	var isSuccess bool
// 	var n int32
// 	var clientErr error = nil
// 	var backendErr error = nil

// 	//TCHDEBUG zap.S().Infof("*****RETURN Backend(%d) => Client(%d)", ctx.pBackConn.Id, ctx.Pid)

// 	if ctx.pSendBackConn.Id != ctx.pBackConn.Id {
// 		zap.S().Panicf("recv backend not the send backend!!!")
// 	}

// 	isSuccess = true
// 	for {
// 		//TCHDEBUG zap.S().Infof("Client(%d): RB(%d): begin ...", ctx.Pid, ctx.pBackConn.Id)
// 		n, _, backendErr = recvMessage(ctx.pBackConn.Conn, ctx.recvBuf[:])
// 		if backendErr != nil {
// 			zap.S().Infof("Client(%d): RB(%d): ERROR: %s", ctx.Pid, ctx.pBackConn.Id, backendErr.Error())
// 			ctx.cliConn.Close()
// 			ctx.BeReconnect()
// 			return clientErr, backendErr
// 		}
// 		//TCHDEBUG zap.S().Infof("Client(%d): RB(%d): data=%c%d%v", ctx.Pid, ctx.pBackConn.Id, ctx.recvBuf[0], n, ctx.recvBuf[:n])
// 		//zap.S().Infof("#### Client(%d): RB(%c)", ctx.Pid, ctx.recvBuf[0])
// 		if ctx.recvBuf[0] == 'Z' { /*ReadyForQuery*/
// 			ctx.transState = ctx.recvBuf[5]
// 		}

// 		if ctx.recvBuf[0] == 'E' {
// 			isSuccess = false
// 			printBackendErrorMessage(ctx.recvBuf[:])
// 		}

// 		if clientErr == nil {
// 			//TCHDEBUG zap.S().Infof("Client(%d): SC: data=%c%d%v", ctx.Pid, ctx.recvBuf[0], n, ctx.recvBuf[:n])
// 			n, clientErr = sendData(ctx.cliConn, ctx.recvBuf[0:n])
// 			if clientErr != nil {
// 				zap.S().Infof("Client(%d): SC: ERROR: %s", ctx.Pid, clientErr.Error())
// 				ctx.cliConn.Close()
// 			}
// 		}

// 		if ctx.recvBuf[0] == 'Z' { /* Ready for Query */
// 			break
// 		}
// 	}
// 	if clientErr != nil {
// 		isSuccess = false
// 	}
// 	if isSuccess {
// 		if !ctx.isInUnnamedPrepared {
// 			for prepareName, cuPre := range ctx.cupreMap {
// 				var pdata *PrepareData
// 				if cuPre.prepareRequestLen == 0 { /* 这是prepare的数据已缓存，而之前这个backend没有parse的情况*/
// 					var ok bool
// 					pdata, ok = ctx.cachedPrepare.Get(prepareName)
// 					if !ok {
// 						zap.S().Panicf("BUG!!!!!!")
// 					}
// 				} else {
// 					pdata = new(PrepareData)
// 					ctx.cachedPrepare.AddPrepare(prepareName, pdata)
// 					pdata.PrepareRequest = cuPre.prepareRequestData
// 				}

// 				pdata.BackendMap = make(map[int32]*PrepareInBackend)
// 				pib := new(PrepareInBackend)
// 				pib.PrepareId = cuPre.backendPrepareId
// 				pib.BackConn = ctx.pBackConn
// 				pib.ReConnCnt = ctx.pBackConn.ReConnCnt /* 把后端连接的当前重连次数记录下来，如果在以后，后端重连后，两者就不一样了，就知道后端被重连了*/
// 				pdata.BackendMap[ctx.pBackConn.Id] = pib
// 				zap.S().Infof("Client(%d): store prepare name=%s to backend(%d), pid=%d",
// 					ctx.Pid, prepareName, ctx.pBackConn.Id, cuPre.backendPrepareId)
// 			}
// 			if len(ctx.cupreMap) > 1 {
// 				zap.S().Infof("many prepare in one request!")
// 			}
// 		}
// 	}

// 	/*把临时放prepare data的map清空*/
// 	ctx.cupreMap = make(map[string]*CuPre)

// 	if (clientErr != nil) || (backendErr != nil) { /*出现一些问题*/
// 		/* 做一些清理工作，把此后端连接上的事务回滚掉*/
// 		if ctx.transState != 'I' {
// 			zap.S().Infof("Client(%d, S): Client is closed, cleanup backend(%d) transacation",
// 				ctx.Pid, ctx.pBackConn.Id)
// 			CleanupTrans(ctx.pBackConn.Conn)
// 		}
// 		if ctx.isGetBackend {
// 			zap.S().Infof("Client(%d, S): release backend(%d)", ctx.Pid, ctx.pBackConn.Id)
// 			atomic.StoreInt32(&ctx.pBackConn.State, 0)
// 			ctx.isGetBackend = false
// 		}
// 		return clientErr, backendErr
// 	}

// 	if !isSuccess {
// 		//zap.S().Panicf("Client(%d, S): ERROR debug!!!", ctx.Pid)
// 	}

// 	/*这是没有发生错误的情况*/
// 	if ctx.transState == 'I' { /*释放后端连接*/
// 		//TCHDEBUG zap.S().Infof("Client(%d, S): release backend(%d)", ctx.Pid, ctx.pBackConn.Id)
// 		atomic.StoreInt32(&ctx.pBackConn.State, 0)
// 		ctx.isGetBackend = false
// 		ctx.pBackConn = nil
// 	}
// 	return nil, nil
// }

// func ExtractSQL(buf []byte) string {
// 	var pos int32
// 	var begin int32
// 	//var prepareName string
// 	if buf[0] != 'P' {
// 		return ""
// 	}
// 	pos = 5
// 	for pos = 5; buf[pos] != 0; pos++ {
// 	}
// 	//prepareName = string(buf[5:pos])
// 	pos++
// 	begin = pos
// 	for pos = begin; buf[pos] != 0; pos++ {
// 	}
// 	return string(buf[begin:pos])
// }

// /*
// 转发数据的函数
// */
// func transData(srcConn net.Conn, dstConn net.Conn, dataLen int32, buf []byte) (error, bool) {
// 	var err error
// 	var ret int
// 	var oprSize int32
// 	var pos int32
// 	var sendLen int32
// 	var leftSize = dataLen

// 	for leftSize > 0 {
// 		if leftSize > DEFAULT_BUF_SIZE {
// 			oprSize = DEFAULT_BUF_SIZE
// 		} else {
// 			oprSize = leftSize
// 		}
// 		ret, err = srcConn.Read(buf[0:oprSize])
// 		if err != nil {
// 			return err, true
// 		}

// 		sendLen = int32(ret)
// 		pos = 0
// 		for pos < sendLen {
// 			ret, err = dstConn.Write(buf[pos:sendLen])
// 			if err != nil {
// 				return err, false
// 			}
// 			pos += int32(ret)
// 		}
// 		leftSize -= sendLen
// 	}
// 	return nil, false
// }

// func getBackend(pool *Pool, rw_state int32) *PgBackendConn {
// 	var cnt = 10
// 	var i int
// 	var pos int = -1
// 	for {
// 		pool.Conf.Lock.Lock()
// 		for i = 0; i < len(pool.Conf.PortalState); i++ {
// 			if pool.Conf.PortalState[i] == rw_state {
// 				pos = i
// 				break
// 			}
// 		}
// 		if pos == -1 && rw_state == 1 { /*没有找到备库节点，则从主库中获得一个*/
// 			for i = 0; i < len(pool.Conf.PortalState); i++ {
// 				if pool.Conf.PortalState[i] == 2 {
// 					pos = i
// 					break
// 				}
// 			}
// 		}
// 		pool.Conf.Lock.Unlock()
// 		if pos != -1 {
// 			for i = 0; i < pool.Conf.BeConns; i++ {
// 				backend := pool.BeConns[i+pos]
// 				if atomic.CompareAndSwapInt32(&backend.State, 0, 1) {
// 					//backend.CleanupNeedClosePrepare()
// 					backend.LifeUsedCount++
// 					return backend
// 				}
// 			}
// 		}
// 		/* 如果没有找到，则等5ms*/
// 		time.Sleep(time.Duration(cnt+1) * 5 * time.Millisecond)
// 		collector.IncreaseBackendConnectionLimitReachedTimes(pool.Conf.ID)
// 		//time.Sleep(time.Millisecond)
// 		cnt += 1
// 		if cnt%10 == 0 {
// 			zap.S().Infof("Wait 10 times for get backend connection!")
// 		}

// 		if cnt > 200 {
// 			cnt = 200
// 		}
// 	}
// 	return nil
// }

// func checkPool() {
// 	var pool *Pool
// 	var backConn *PgBackendConn
// 	for {
// 		time.Sleep(10 * time.Second)
// 		for _, pool = range g_backend_pool {
// 			for _, backConn = range pool.BeConns {
// 				if atomic.CompareAndSwapInt32(&backConn.State, 0, 1) {
// 					zap.S().Debugf("checkPool: get backend(%d)", backConn.Id)
// 					backConn.CleanupNeedClosePrepare()
// 					if pool.Conf.BeConnLifeTime > 0 && backConn.LifeUsedCount > 0 {
// 						if time.Now().Unix()-backConn.ConnUnixTime > int64(pool.Conf.BeConnLifeTime) {
// 							portal := backConn.Reconnect(pool.Conf)
// 							zap.S().Infof("backConn(%d) life cycle has ended, release and reconnect %s", backConn.Id, portal)
// 							backConn.LifeUsedCount = 0
// 						}
// 					}
// 					atomic.StoreInt32(&backConn.State, 0)
// 					zap.S().Debugf("checkPool: release backend(%d)", backConn.Id)
// 				}
// 			}
// 		}
// 	}
// }

// atomic.StoreInt32(&ctx.pBackConn.State, 0)
